#include <iostream>
#include <set>

template <typename T>
void Print(const T &v)
{
    for (auto ite = v.begin(); ite != v.end(); ite++)
    {
        std::cout << *ite << " ";
    }
    std::cout << std::endl;
}

// 定义一个学生结构体
struct Student
{
    int id;
    std::string name;
};

// 全局重载
bool operator<(const Student &s1, const Student &s2)
{
    // 按id排
    // return s1.name < s2.name;
    // 按名字排
    return s1.name < s2.name;
}

bool operator>(const Student &s1, const Student &s2)
{
    return s1.name > s2.name;
}

std::ostream &operator<<(std::ostream &os, const Student &s)
{
    os << s.id << " " << s.name << std::endl;
    return os;
}

int main()
{
#if 0
    int a[] = {5, 3, 1, 4, 2};
    std::set<int> s;
    for (int i = 0; i < 5; i++)
    {
        s.insert(a[i]);
    }
    Print(s);
#endif

#if 0
    // set容器里的值唯一（可以利用这个特性对一组数据进行去重）
    int a[] = {5, 3, 1, 4, 2};
    std::set<int> s;
    for (int i = 0; i < 5; i++)
    {
        s.insert(a[i]);
    }

    s.insert(2);
    Print(s);
#endif

#if 0
    int a[] = {5, 3, 1, 4, 2};
    std::set<int> s;
    for (int i = 0; i < 5; i++)
    {
        s.insert(a[i]);
    }
    // 按值删
    s.erase(2);
    Print(s);

    // 查找（返回值是迭代器）
    auto ite = s.find(3);
    // 按迭代器删
    s.erase(ite);
    Print(s);
#endif

#if 0
    int a[] = {5, 3, 1, 4, 2};
    std::set<int> s;
    for (int i = 0; i < 5; i++)
    {
        s.insert(a[i]);
    }
    // 找不到就返回尾部迭代器
    auto ite = s.find(12);
    if(ite != s.end())
        s.erase(ite);
    Print(s);
#endif

#if 0
    // 结构体不能像int那样直接排序，需要规定一个重载的规则
    std::set<Student> s;
    s.insert({1, "zhangsan"});
    s.insert({3, "lisi"});
    s.insert({2, "wangwu"});
    Print(s);
#endif

#if 1
    // 从大到小排（要重载 >）
    std::set<Student, std::greater<Student>> s;
    s.insert({1, "zhangsan"});
    s.insert({3, "lisi"});
    s.insert({2, "wangwu"});
    Print(s);
#endif

    return 0;
}